package edu.study.user.service;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import com.github.pagehelper.Page;

import edu.study.api.common.dto.BaseRespDto;
import edu.study.api.common.dto.PageRespDto;
import edu.study.api.common.dto.RespDto;
import edu.study.api.common.enums.BaseResultCodeEnum;
import edu.study.api.common.enums.RoleTypeEnum;
import edu.study.api.common.enums.StatusTypeEnum;
import edu.study.common.util.BeanCopy;
import edu.study.common.util.cache.Cache;
import edu.study.user.api.dto.AuthAndSubDto;
import edu.study.user.api.dto.AuthDto;
import edu.study.user.api.dto.UserDetailDto;
import edu.study.user.api.req.auth.AddAuthReq;
import edu.study.user.api.req.auth.DeleteAuthReq;
import edu.study.user.api.req.auth.ModifyAuthReq;
import edu.study.user.api.req.auth.ModifyAuthStatusReq;
import edu.study.user.api.req.auth.QueryAuthPageListReq;
import edu.study.user.api.req.auth.QueryAuthReq;
import edu.study.user.dao.mapperExt.AuthDOMapperExt;
import edu.study.user.dbBean.AuthDO;
import edu.study.user.util.UserUtils;
import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class AuthService {

	@Autowired
	private AuthDOMapperExt authDOMapperExt;
	
	@Autowired
	private Cache cache;

	public BaseRespDto addAuth(AddAuthReq req) {
		BaseRespDto resp = new BaseRespDto();
				
		if(!StringUtils.isEmpty(req.getParentAuthNo()) && !RoleTypeEnum.ROOT.getCode().equals(req.getParentAuthNo())){
			AuthDO checkAuthDO = authDOMapperExt.queryByAuthNo(req.getParentAuthNo());
			if(checkAuthDO == null) {
				log.info("AuthService.addAuth, 父权限不存在! authNo={}", req.getParentAuthNo());
				resp.setResultFail(BaseResultCodeEnum.RECORD_NOT_FOUND);
				return resp;
			}
			checkAuthDO = authDOMapperExt.queryAuthForCheck(req.getParentAuthNo(), req.getAuthName());
			if (checkAuthDO != null) {
				log.info("AuthService.addAuth, 同一个父权限下面的子权限不允许名称一样! parentAuthNo={}, authName={}", req.getParentAuthNo(), req.getAuthName());
				resp.setResultFail(BaseResultCodeEnum.RECORD_ALREADY_EXISTS);
				return resp;
			}
		}
		if(StringUtils.isEmpty(req.getParentAuthNo()) || RoleTypeEnum.ROOT.getCode().equals(req.getParentAuthNo())){
			AuthDO checkAuthDO = authDOMapperExt.queryAuthForCheck(RoleTypeEnum.ROOT.getCode(), req.getAuthName());
			if (checkAuthDO != null) {
				log.info("AuthService.addAuth, 一级权限不允许名称一样! authName={}", req.getAuthName());
				resp.setResultFail(BaseResultCodeEnum.RECORD_ALREADY_EXISTS);
				return resp;
			}
		}
		AuthDO newAuthDO = new AuthDO();
		BeanCopy.copyFromSrcToDest(req, newAuthDO);
		String authNo = cache.generateStr("authNo_", 1, null);
		newAuthDO.setAuthNo(authNo);
		UserDetailDto userDetailDto = UserUtils.getCurrentUser();
		if(userDetailDto!=null) {
			newAuthDO.setCreator(userDetailDto.getLoginName());
			newAuthDO.setModifier(userDetailDto.getLoginName());
		}
		int i = authDOMapperExt.insertSelective(newAuthDO);
		if (i == 0) {
			resp.setResultFail(BaseResultCodeEnum.DB_ERROR);
			return resp;
		}
		return resp;
	}

	public BaseRespDto deleteAuth(DeleteAuthReq req) {
		BaseRespDto resp = new BaseRespDto();

		AuthDO authDO = authDOMapperExt.queryByAuthNo(req.getAuthNo());
		if (authDO == null) {
			resp.setResultFail(BaseResultCodeEnum.RECORD_NOT_FOUND);
			return resp;
		}
		//todo 删除了，关联的数据怎么处理？？？
		AuthDO newAuthDO = new AuthDO();
		newAuthDO.setId(authDO.getId());
		newAuthDO.setIsDeleted(StatusTypeEnum.Y.getCode());
		int i = authDOMapperExt.updateByPrimaryKeySelective(newAuthDO);
		if (i == 0) {
			resp.setResultFail(BaseResultCodeEnum.DB_ERROR);
			return resp;
		}
		return resp;
	}
	
	public BaseRespDto modifyAuth(ModifyAuthReq req) {
		BaseRespDto resp = new BaseRespDto();

		AuthDO authDO = authDOMapperExt.queryByAuthNo(req.getAuthNo());
		if (authDO == null) {
			resp.setResultFail(BaseResultCodeEnum.RECORD_NOT_FOUND);
			return resp;
		}
		
		//校验有没有修改权限名称
		if(!StringUtils.isEmpty(req.getAuthName()) && !authDO.getAuthName().equals(req.getAuthName())) {
			if(!StringUtils.isEmpty(authDO.getParentAuthNo()) && !RoleTypeEnum.ROOT.getCode().equals(authDO.getParentAuthNo())){
				AuthDO checkAuthDO = authDOMapperExt.queryAuthForCheck(authDO.getParentAuthNo(), req.getAuthName());
				if (checkAuthDO != null && !checkAuthDO.getAuthNo().equals(req.getAuthNo())) {
					log.info("AuthService.modifyAuth, 同一个父权限下面的子权限不允许名称一样! parentAuthNo={}, authName={}", authDO.getParentAuthNo(), req.getAuthName());
					resp.setResultFail(BaseResultCodeEnum.RECORD_ALREADY_EXISTS);
					return resp;
				}
			}
			if(StringUtils.isEmpty(authDO.getParentAuthNo()) || RoleTypeEnum.ROOT.getCode().equals(authDO.getParentAuthNo())){
				AuthDO checkAuthDO = authDOMapperExt.queryAuthForCheck(RoleTypeEnum.ROOT.getCode(), req.getAuthName());
				if (checkAuthDO != null) {
					log.info("AuthService.modifyAuth, 一级权限不允许名称一样! authName={}", req.getAuthName());
					resp.setResultFail(BaseResultCodeEnum.RECORD_ALREADY_EXISTS);
					return resp;
				}
			}
		}
		
		AuthDO newAuthDO = new AuthDO();
		BeanCopy.copyFromSrcToDest(req, newAuthDO);
		newAuthDO.setAuthNo(null);
		newAuthDO.setId(authDO.getId());
		UserDetailDto userDetailDto = UserUtils.getCurrentUser();
		if(userDetailDto!=null) {
			newAuthDO.setModifier(userDetailDto.getLoginName());
		}
		int i = authDOMapperExt.updateByPrimaryKeySelective(newAuthDO);
		if (i == 0) {
			resp.setResultFail(BaseResultCodeEnum.DB_ERROR);
			return resp;
		}
		return resp;
	}
	
	public BaseRespDto modifyAuthStatus(ModifyAuthStatusReq req) {
		BaseRespDto resp = new BaseRespDto();

		AuthDO authDO = authDOMapperExt.queryByAuthNo(req.getAuthNo());
		if (authDO == null) {
			resp.setResultFail(BaseResultCodeEnum.RECORD_NOT_FOUND);
			return resp;
		}
		if(req.getStatus().equals(authDO.getStatus())) {
			log.info("AuthService.modifyAuthStatus, 不用修改, authNo={}", req.getAuthNo());
			return resp;
		}
		//todo 失效了，关联的数据怎么处理？？？
		AuthDO newAuthDO = new AuthDO();
		newAuthDO.setId(authDO.getId());
		newAuthDO.setStatus(req.getStatus());
		UserDetailDto userDetailDto = UserUtils.getCurrentUser();
		if(userDetailDto!=null){
			newAuthDO.setModifier(userDetailDto.getLoginName());
		}
		int i = authDOMapperExt.updateByPrimaryKeySelective(newAuthDO);
		if (i == 0) {
			resp.setResultFail(BaseResultCodeEnum.DB_ERROR);
			return resp;
		}
		return resp;
	}
	
	public RespDto<AuthDto> queryAuth(QueryAuthReq req) {
		RespDto<AuthDto> resp = new RespDto<AuthDto>();

		AuthDO authDO = authDOMapperExt.queryByAuthNo(req.getAuthNo());
		if (authDO == null) {
			resp.setResultFail(BaseResultCodeEnum.RECORD_NOT_FOUND);
			return resp;
		}
		AuthDto authDto = new AuthDto();
		BeanCopy.copyFromSrcToDest(authDO, authDto);
		resp.setData(authDto);
		return resp;
	}
		
	public PageRespDto<AuthAndSubDto> queryAuthPageList(QueryAuthPageListReq req) {
		PageRespDto<AuthAndSubDto> resp = new PageRespDto<AuthAndSubDto>();
		if(StringUtils.isEmpty(req.getParentAuthNo())) {
			req.setParentAuthNo(RoleTypeEnum.ROOT.getCode());//默认从一级权限查起
		}
		
		Page<AuthDto> authDtoPageList = authDOMapperExt.queryAuthPageList(req);
		if (authDtoPageList != null && !CollectionUtils.isEmpty(authDtoPageList.getResult())) {
			resp.setPages(authDtoPageList.getPages());
			resp.setTotal(authDtoPageList.getTotal());
			//resp.setData(authDtoPageList.getResult());
			
			List<AuthAndSubDto> authAndSubDtoList = new ArrayList<AuthAndSubDto>();
			for (AuthDto authDto : authDtoPageList) {
				QueryAuthReq queryAuthReq = new QueryAuthReq();
				queryAuthReq.setAuthNo(authDto.getAuthNo());
				RespDto<AuthAndSubDto> authAndSubDto = queryAuthAndSub(queryAuthReq);
				authAndSubDtoList.add(authAndSubDto.getData());
			}
			resp.setData(authAndSubDtoList);
		}
		return resp;
	}
	
	public RespDto<List<AuthDto>> queryAuthAndSubList(QueryAuthReq req) {
		RespDto<List<AuthDto>> resp = new RespDto<List<AuthDto>>();
		
		AuthDO authDO = authDOMapperExt.queryByAuthNo(req.getAuthNo());
		if (authDO == null) {
			resp.setResultFail(BaseResultCodeEnum.RECORD_NOT_FOUND);
			return resp;
		}
		List<AuthDto> authDtoList = new ArrayList<AuthDto>();
		AuthDto authDto = new AuthDto();
		BeanCopy.copyFromSrcToDest(authDO, authDto);
		authDtoList.add(authDto);
		
		this.querySubAuthList(authDto, authDtoList);
		
		resp.setData(authDtoList);		
		return resp;
	}
	
	private void querySubAuthList(AuthDto authDto, List<AuthDto> authDtoListAll) {
		List<AuthDto> authDtoList = authDOMapperExt.queryByParentAuthNo(authDto.getAuthNo());
		if (!CollectionUtils.isEmpty(authDtoList)) {
			authDtoListAll.addAll(authDtoList);
			for (AuthDto item : authDtoList) {
				this.querySubAuthList(item, authDtoListAll);
			}
		}
	}
	
	/**
	 * 可能用不到
	 */
	public RespDto<AuthAndSubDto> queryAuthAndSub(QueryAuthReq req) {
		RespDto<AuthAndSubDto> resp = new RespDto<AuthAndSubDto>();
		
		AuthDO authDO = authDOMapperExt.queryByAuthNo(req.getAuthNo());
		if (authDO == null) {
			resp.setResultFail(BaseResultCodeEnum.RECORD_NOT_FOUND);
			return resp;
		}
		
		AuthAndSubDto authAndSubDto = new AuthAndSubDto();
		BeanCopy.copyFromSrcToDest(authDO, authAndSubDto);
		
		authAndSubDto = this.querySubAuth(authAndSubDto);
		
		resp.setData(authAndSubDto);
		return resp;
	}
	
	/**
	 * 可能用不到
	 */
	private AuthAndSubDto querySubAuth(AuthAndSubDto authAndSubDto) {
		List<AuthDto> authDtoList = authDOMapperExt.queryByParentAuthNo(authAndSubDto.getAuthNo());
		if (!CollectionUtils.isEmpty(authDtoList)) {
			List<AuthAndSubDto> subAuthList = new ArrayList<AuthAndSubDto>();
			for (AuthDto item : authDtoList) {
				AuthAndSubDto subAuth = new AuthAndSubDto();
				BeanCopy.copyFromSrcToDest(item, subAuth);
				subAuth = querySubAuth(subAuth);
				subAuthList.add(subAuth);
			}
			authAndSubDto.setSubAuthList(subAuthList);
		}
		return authAndSubDto;
	}
}
